package session

import (
	"gitee.com/youkelike/web"
	"github.com/google/uuid"
)

// manager 是一个方便管理 session 生命周期的代理类
type Manager struct {
	Store
	Propagator
}

// 登陆成功后要把 session 初始化，然后把 session id 写入 cookie 中
func (m *Manager) InitSession(ctx *web.Context) (Session, error) {
	id := uuid.New().String()
	sess, err := m.Generate(ctx.Req.Context(), id)
	if err != nil {
		return nil, err
	}

	err = m.Inject(id, ctx.Resp)
	return sess, err
}

// 取出 session 对象，可以利用 session 对象进行数据操作
// 缓存到 context 上加速读取
func (m *Manager) GetSession(ctx *web.Context) (Session, error) {
	if ctx.UserValues == nil {
		ctx.UserValues = make(map[string]any, 1)
	}

	sessId, err := m.Extract(ctx.Req)
	if err != nil {
		return nil, err
	}
	val, ok := ctx.UserValues[sessId]
	if ok {
		return val.(Session), nil
	}

	sess, err := m.Get(ctx.Req.Context(), sessId)
	if err != nil {
		return nil, err
	}
	ctx.UserValues[sessId] = sess
	return sess, nil
}

// 刷新 session 过期时间
func (m *Manager) RefreshSession(ctx *web.Context) error {
	sessId, err := m.Extract(ctx.Req)
	if err != nil {
		return err
	}
	return m.Refresh(ctx.Req.Context(), sessId)
}

// 移除 session 包括两步：删除 session 对象 和 删除 cookie 中的 session id
func (m *Manager) RemoveSession(ctx *web.Context) error {
	sess, err := m.GetSession(ctx)
	if err != nil {
		return err
	}

	err = m.Store.Remove(ctx.Req.Context(), sess.ID())
	if err != nil {
		return err
	}

	return m.Propagator.Remove(ctx.Resp)
}
